package com.qiall.omsserver.service.dubbo;

import com.qiall.boot.cache.ability.service.CacheService;
import com.qiall.oms.service.DubboClientClassUplodListener;
import org.apache.dubbo.common.deploy.DeployState;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.spring.context.event.DubboApplicationStateEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

import java.io.*;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.qiall.oms.constants.OmsManageConstant.*;

@Component
public class UploadCommonPackageService {
    @DubboReference
    private CacheService cacheService;
    private static final String JAR_COMMON_NANE = "qiall-common";

    @EventListener(classes = {DubboApplicationStateEvent.class})
    public void run(DubboApplicationStateEvent event) {

        if (!event.getState().equals(DeployState.STARTED)) {
            return;
        }
        String path = new DubboClientClassUplodListener().getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
        // 构建jar包路径
        path = subString(path, "file:", "!/BOOT-INF/lib/");
        try {
            JarFile jarFile = new JarFile(path);
            Enumeration<JarEntry> enumFiles = jarFile.entries();
            // 获取 client jar包
            while (enumFiles.hasMoreElements()) {
                JarEntry jarEntry = enumFiles.nextElement();
                if (jarEntry.getName().contains(JAR_COMMON_NANE)) {
                    InputStream input = jarFile.getInputStream(jarEntry);
                    File file = new File(COMMON_NAME);
                    FileOutputStream fileOutputStream = new FileOutputStream(file);
                    byte[] buffer = new byte[64];
                    while (true) {
                        if (!(input.read(buffer) != -1)) {
                            break;
                        }
                        fileOutputStream.write(buffer);
                    }
                    fileOutputStream.close();
                    input.close();
                    break;
                }

            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            syncClientClass();
        } catch (IOException e) {
            e.printStackTrace();
        }


    }

    public static String subString(String str, String strStart, String strEnd) {
        /* 找出指定的2个字符在 该字符串里面的 位置 */
        int strStartIndex = str.indexOf(strStart);
        int strEndIndex = str.indexOf(strEnd);
        // 如果俩个字符相同，结束字符为第二个
        if (strStart.equalsIgnoreCase(strEnd)) {
            int fromIndex = getFromIndex(str, strEnd, 2);
            strEndIndex = fromIndex;
        }

        /* index 为负数 即表示该字符串中 没有该字符 */
        if (strStartIndex < 0) {
            return "字符串 :---->" + str + "<---- 中不存在 " + strStart + ", 无法截取目标字符串";
        }
        if (strEndIndex < 0) {
            return "字符串 :---->" + str + "<---- 中不存在 " + strEnd + ", 无法截取目标字符串";
        }
        /* 开始截取 */
        String result = str.substring(strStartIndex, strEndIndex).substring(strStart.length());
        return result;
    }

    private static int getFromIndex(String str, String modelStr, Integer count) {
        //对子字符串进行匹配
        Matcher slashMatcher = Pattern.compile(modelStr).matcher(str);
        int index = 0;
        //matcher.find();尝试查找与该模式匹配的输入序列的下一个子序列
        while (slashMatcher.find()) {
            index++;
            //当modelStr字符第count次出现的位置
            if (index == count) {
                break;
            }
        }
        //matcher.start();返回以前匹配的初始索引。
        return slashMatcher.start();
    }


    private void syncClientClass() throws IOException {
        JarFile jarFile = new JarFile(COMMON_NAME);
        Enumeration<JarEntry> enumFiles = jarFile.entries();
        while (enumFiles.hasMoreElements()) {
            JarEntry jarEntry = enumFiles.nextElement();
            if (jarEntry.isDirectory()) {
                continue;
            }
            if (!jarEntry.getName().contains(".class")) {
                continue;
            }
            InputStream input = jarFile.getInputStream(jarEntry);
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            byte[] buffer = new byte[1];
            while (true) {
                if (!(input.read(buffer) != -1)) {
                    break;
                }
                byteArrayOutputStream.write(buffer);
            }
            byte[] ret = byteArrayOutputStream.toByteArray();
            cacheService.setMapValue(CLIENT_CLASS_NAME_MAP, jarEntry.getName(), new String(ret, CLIENT_CLASS_DATA_CHARSET));
            input.close();
            byteArrayOutputStream.close();
        }
    }


}
